using System;
using System.Web;
using Microsoft.Practices.CompositeWeb.Interfaces;
using Microsoft.Practices.ObjectBuilder;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WCSFContrib.Extensions.CompositeWeb.BuilderStrategies;
using WCSFContrib.Extensions.CompositeWeb.Tests.Mocks;
using WCSFContrib.Extensions.CompositeWeb.Web;

namespace WCSFContrib.Extensions.CompositeWeb.Tests.BuilderStrategies
{
    /// <summary>
    /// Summary description for QueryStringBindingStrategyFixture
    /// </summary>
    [TestClass]
    public class QueryStringBindingStrategyFixture
    {
        [TestMethod]
        public void KeyNameAssignedTest()
        {
            QueryStringBindingStrategy strategy = new QueryStringBindingStrategy();
            MockHttpContext httpContext = new MockHttpContext();
            httpContext.Request = new HttpRequest(string.Empty, "http://www.davidhayden.com/", string.Empty);
            MockHttpContextLocatorService httpContextLocator = new MockHttpContextLocatorService(httpContext);
            MockBuilderContext builderContext = new MockBuilderContext(strategy);
            builderContext.Locator.Add(new DependencyResolutionLocatorKey(typeof(IHttpContextLocatorService), null), httpContextLocator);

            SampleClass sample = new SampleClass();

            strategy.BuildUp(builderContext, typeof(SampleClass), sample, null);

            Assert.AreEqual("String1", sample.String1.KeyName);
            Assert.AreEqual("key", sample.String2.KeyName);
        }

        [TestMethod]
        public void ValuesArePulledFromQueryStringTest()
        {
            QueryStringBindingStrategy strategy = new QueryStringBindingStrategy();
            MockHttpContext httpContext = new MockHttpContext();
            httpContext.Request = new HttpRequest(string.Empty, "http://www.davidhayden.com/", "key=value&String1=value2");
            MockHttpContextLocatorService httpContextLocator = new MockHttpContextLocatorService(httpContext);
            MockBuilderContext builderContext = new MockBuilderContext(strategy);
            builderContext.Locator.Add(new DependencyResolutionLocatorKey(typeof(IHttpContextLocatorService), null), httpContextLocator);

            SampleClass sample = new SampleClass();
            strategy.BuildUp(builderContext, typeof(SampleClass), sample, null);

            Assert.AreEqual("value2", sample.String1.Value);
            Assert.AreEqual("value", sample.String2.Value);
        }

        [TestMethod]
        public void DateTimeValuesProperlyConvertedFromQueryStringTest()
        {
            QueryStringBindingStrategy strategy = new QueryStringBindingStrategy();
            MockHttpContext httpContext = new MockHttpContext();
            httpContext.Request = new HttpRequest(string.Empty, "http://www.davidhayden.com/", "MyDate=1/1/2008");
            MockHttpContextLocatorService httpContextLocator = new MockHttpContextLocatorService(httpContext);
            MockBuilderContext builderContext = new MockBuilderContext(strategy);
            builderContext.Locator.Add(new DependencyResolutionLocatorKey(typeof(IHttpContextLocatorService), null), httpContextLocator);

            SampleClass sample = new SampleClass();
            strategy.BuildUp(builderContext, typeof(SampleClass), sample, null);

            Assert.AreEqual(new DateTime(2008, 1, 1), sample.MyDate.Value);
        }

        [TestMethod]
        public void IntegerValuesProperlyConvertedFromQueryStringTest()
        {
            QueryStringBindingStrategy strategy = new QueryStringBindingStrategy();
            MockHttpContext httpContext = new MockHttpContext();
            httpContext.Request = new HttpRequest(string.Empty, "http://www.davidhayden.com/", "MyInt=5");
            MockHttpContextLocatorService httpContextLocator = new MockHttpContextLocatorService(httpContext);
            MockBuilderContext builderContext = new MockBuilderContext(strategy);
            builderContext.Locator.Add(new DependencyResolutionLocatorKey(typeof(IHttpContextLocatorService), null), httpContextLocator);

            SampleClass sample = new SampleClass();
            strategy.BuildUp(builderContext, typeof(SampleClass), sample, null);

            Assert.AreEqual(5, sample.MyInt.Value);
        }

        /* [Test]
        public void GuidValuesProperlyConvertedFromQueryStringTest()
        {
            Guid guid = new Guid("B80D56EC-5899-459d-83B4-1AE0BB8418E4");

            QueryStringBindingStrategy strategy = new QueryStringBindingStrategy();
            MockHttpContext httpContext = new MockHttpContext();
            httpContext.Request = new HttpRequest(string.Empty, "http://www.davidhayden.com/", "MyGuid=B80D56EC-5899-459d-83B4-1AE0BB8418E4");
            MockHttpContextLocatorService httpContextLocator = new MockHttpContextLocatorService(httpContext);
            MockBuilderContext builderContext = new MockBuilderContext(strategy);
            builderContext.Locator.Add(new DependencyResolutionLocatorKey(typeof(IHttpContextLocatorService), null), httpContextLocator);

            SampleClass sample = new SampleClass();
            strategy.BuildUp(builderContext, typeof(SampleClass), sample, null);

            Assert.AreEqual(guid, sample.MyGuid.Value);
        } */

        [TestMethod]
        public void MissingQueryStringValuesResultInDefaultValuesTest()
        {
            QueryStringBindingStrategy strategy = new QueryStringBindingStrategy();
            MockHttpContext httpContext = new MockHttpContext();
            httpContext.Request = new HttpRequest(string.Empty, "http://www.davidhayden.com/", string.Empty);
            MockHttpContextLocatorService httpContextLocator = new MockHttpContextLocatorService(httpContext);
            MockBuilderContext builderContext = new MockBuilderContext(strategy);
            builderContext.Locator.Add(new DependencyResolutionLocatorKey(typeof(IHttpContextLocatorService), null), httpContextLocator);

            SampleClass sample = new SampleClass();
            strategy.BuildUp(builderContext, typeof(SampleClass), sample, null);

            Assert.AreEqual(GetDefault<string>(), sample.String1.Value);
            Assert.AreEqual(GetDefault<string>(), sample.String2.Value);
            Assert.AreEqual(GetDefault<DateTime>(), sample.MyDate.Value);
            Assert.AreEqual(GetDefault<int>(), sample.MyInt.Value);
            // Assert.AreEqual(GetDefault<Guid>(), sample.MyGuid.Value);
            Assert.AreEqual(GetDefault<DateTime?>(), sample.MyNullableDate.Value);
            Assert.AreEqual(GetDefault<int?>(), sample.MyNullableInt.Value);
            // Assert.AreEqual(GetDefault<Guid?>(), sample.MyNullableGuid.Value);

        }

        public class SampleClass
        {
            public QueryStringValue<string> String1;

            [QueryStringKey("key")]
            public QueryStringValue<string> String2;

            public QueryStringValue<DateTime> MyDate;
            public QueryStringValue<int> MyInt;
            // public QueryStringValue<Guid> MyGuid;

            public QueryStringValue<DateTime?> MyNullableDate;
            public QueryStringValue<int?> MyNullableInt;
            // public QueryStringValue<Guid?> MyNullableGuid;
        }

        private static T GetDefault<T>()
        {
            return default(T);
        }
    }
}
